package com.idea.relax.boot.jackson;

import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import lombok.AllArgsConstructor;

import java.time.temporal.TemporalAccessor;
import java.util.*;

/**
 * @author: 沉香
 * @date: 2023/4/3
 * @description:
 */
@AllArgsConstructor
public class RelaxBeanSerializerModifier extends BeanSerializerModifier {

	private final RelaxJacksonProperties properties;

	@Override
	public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
													 BeanDescription beanDesc,
													 List<BeanPropertyWriter> beanProperties) {

		beanProperties.forEach(writer -> {
			// 如果已经有 null 序列化处理如注解：@JsonSerialize(nullsUsing = xxx) 跳过
			if (writer.hasNullSerializer()) {
				return;
			}
			if (properties.getUseNullSerializers()) {
				JavaType type = writer.getType();
				Class<?> clazz = type.getRawClass();
				if (type.isTypeOrSubTypeOf(String.class)) {
					writer.assignNullSerializer(new NullJsonSerializers.StringJsonSerializer());
				} else if (type.isTypeOrSubTypeOf(Number.class)) {
					writer.assignNullSerializer(new NullJsonSerializers.NumberJsonSerializer());
				} else if (type.isArrayType() || clazz.isArray() || type.isTypeOrSubTypeOf(Collection.class)) {
					writer.assignNullSerializer(new NullJsonSerializers.ArrayJsonSerializer());
				} else if (type.isTypeOrSubTypeOf(Date.class) || type.isTypeOrSubTypeOf(TemporalAccessor.class)) {
					writer.assignNullSerializer(new NullJsonSerializers.StringJsonSerializer());
				} else if (type.isTypeOrSubTypeOf(Character.class)) {
					writer.assignNullSerializer(new NullJsonSerializers.StringJsonSerializer());
				} else if (type.isTypeOrSubTypeOf(Boolean.class)) {
					writer.assignNullSerializer(new NullJsonSerializers.BooleanJsonSerializer());
				} else {
					writer.assignNullSerializer(new NullJsonSerializers.ObjectJsonSerializer());
				}
			}
		});
		return super.changeProperties(config, beanDesc, beanProperties);
	}
}
